#define _CRT_SECURE_NO_WARNINGS 1
#include"queue.h"

void QNInit(Queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
	pq->size = 0;
}
void QNDestroy(Queue* pq)
{
	assert(pq);
	struct QueueNode* cur = pq->head;
	while (cur)
	{
		struct QueueNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = NULL;
	pq->size = 0;
}

void QNPush(Queue* pq, QueueDataType x)
{
	assert(pq);
	struct QueueNode* newnode = (struct QueueNode*)malloc(sizeof(struct QueueNode));
	newnode->next = NULL;
	newnode->data = x;
	if (pq->head == NULL)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
	pq->size++;
}


bool QNEmpty(Queue* pq)
{
	return pq->size == 0;
}

void QNPop(Queue* pq)
{
	assert(pq);
	assert(!QNEmpty(pq));
	if (pq->size > 1)
	{
		struct QueueNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
	else
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	pq->size--;
}

QueueDataType QNTop(Queue* pq)
{
	assert(pq);
	assert(!QNEmpty(pq));
	return pq->head->data;
}
QueueDataType QNFront(Queue* pq)
{
	assert(pq);
	assert(QNEmpty(pq));
	return pq->head->data;
}

QueueDataType QNBack(Queue* pq)
{
	assert(pq);
	assert(QNEmpty(pq));
	return pq->tail->data;
}